<template>
  <div ref="componentRef" class="component">

<!--    :scroll="{ x: MyTable.overWidth, y: 57 * MyTable.pageConfig.pageSizeOptions[0] }"-->

    <a-table
        :columns="MyTable.columns"
        :data-source="MyTable.datas"
        :scroll="false"
        :pagination="MyTable.pageConfig"
        :row-key="MyTable.key"
        :row-selection="MyTable.selection"
        bordered
        row-class-name="tableBorder"
    >
      <!-- slot对应配置文件中customRender的内容，为避免冲突和歧义，建议以c-开头命名 -->
      <template #bodyCell="{ column, record,index }">
        <!-- index -->
        <div v-if="column.slot === 'c-index'">
          {{ index+1 }}
        </div>
        <!-- 自定义 html 文本 -->
        <div v-if="column.slot === 'c-html'" v-html="record[column.key]"/>
        <!-- switch -->
        <a-switch
            v-if="column.slot === 'c-switch'"
            :checked="record[column.key]"
            disabled
        />
        <!-- link -->
        <a
            v-if="column.slot === 'c-link'"
            :href="record[column.key]"
            target="_blank"
        >点击跳转链接</a>
        <!-- tag -->
        <!-- 由于 tag 存在偏移，需要增加外边距，具体视使用情况而定 -->
        <a-tag
            v-if="column.slot === 'c-tag'"
            :color="record.tagColor"
            class="c-tag"
        >
          {{ record[column.key] }}
        </a-tag>
        <!-- pop -->
        <!-- 此处 pop 弹窗仅示例，请根据需求自行修改 -->
        <a-popover
            v-if="column.slot === 'c-pop'"
            :get-popup-container="() => componentRef.value"
            title="详情"
            trigger="click"
        >
          <template #content>
            <div v-for="(item, index) in record[column.key]" :key="index">
              {{ item }}
            </div>
          </template>
          <a>点击查看详情</a>
        </a-popover>
        <!-- image -->
        <!-- 缩略图大小可自行调整，见样式文件 -->
        <a-popover
            v-if="column.slot === 'c-image'"
            :get-popup-container="() => componentRef.value"
            title="预览图"
            trigger="hover"
        >
          <template #content>
            <div :style="{backgroundImage: `url(${record[column.key]})`}" class="c-image preview"/>
          </template>
          <div :style="{backgroundImage: `url(${record[column.key]})`}" class="c-image"/>
        </a-popover>
        <!-- multiline -->
        <template v-if="column.slot === 'c-multi'">
          <div v-for="(item, index) in record[column.key]" :key="index">
            {{ item }}
          </div>
        </template>
        <!--        c-roles-->
        <div v-if="column.slot === 'c-roles'" :class="column.type?column.type[record[column.key]]:''">
          {{ column.option[record[column.key]] }}
        </div>
        <!--        c-select-->
        <div v-if="column.slot === 'c-select'">
          <a-select
              v-model:value="record[column.key]"
              :bordered="column.bordered"
              :placeholder="column.hint || `请选择`"
              :size="column.size"
              allow-clear
          >
            <a-select-option
                v-for="selection in column.items"
                :key="selection.id"
                :value="selection.id"
            >
              {{ selection.name }}
            </a-select-option>
          </a-select>
        </div>
        <!--                c-number-->
        <div v-if="column.slot === 'c-number'" class="numberInput">
          <a-input-number id="inputNumber"
                          v-model:value="record[column.key]" :bordered="column.bordered" :max="17" :min="1" size="small"
          />
        </div>

        <!-- action -->
        <div v-if="column.slot === 'c-action'">
          <a
              v-for="(btn, btnIndex) in column.items"
              :key="btn.name"
              :style="{ color: btn.color }"
              @click="btn.callback(record)"
          >
            <span>{{ btn.name }}</span>
            <a-divider v-if="btnIndex < column.items.length - 1" type="vertical"/>
          </a>
        </div>
        <!-- text -->
        <div v-if="column.slot === 'c-text'" class="c-text">
         {{ record[column.key] }}
        </div>
      </template>
    </a-table>
  </div>
</template>

<script setup>
import {ref} from "@vue/reactivity";
import {inject, onMounted} from "@vue/runtime-core";

/**
 * -- input --
 * datas {Array} 表格数据，非测试情况下尽量不要直接赋值
 * columns {Array} 表格配置，可以在父组件 mount 完成之前使用
 * key {string} 表格项键名称
 * selection {object} 表格选择器配置，具体配置方式参考 Antd Vue 文档说明
 * overWidth {number} 表格最小宽度，小于这个宽度时会显示滚动条
 * pageSize {number} 表格分页大小
 * getData {Function} 点击分页后数据变化回调方法，有 2 个参数，分别为当前页面和当前分页大小
 */

/**
 * -- output --
 * setData {Function} 设置表格数据，可以同时设置页面和总数据大小，建议使用这个方法代替直接设置 datas 属性值，不要在父组件 mount 完成之前使用
 * setColumns {Function} 设置表格配置，可以自动设置部分必要的属性值，建议使用这个方法代替直接设置 columns 属性值，不要在父组件 mount 完成之前使用
 */

// def
const componentRef = ref(null);
const MyTable = inject("MyTable");
const isLoading = inject("isLoading");

// datas
MyTable.datas ||= [];
MyTable.columns ||= [];
MyTable.key ||= "id";
MyTable.selection ||= null;
MyTable.overWidth ||= 1000;
MyTable.pageConfig = {
  current: 1,
  pageSize: MyTable.pageSize || 10,
  total: 0,
  pageSizeOptions: [String(MyTable.pageSize)],
  // showSizeChanger: true,
  showQuickJumper: true,
  onChange: (cur, size) => {
    MyTable.pageConfig.current = cur;
    MyTable.pageConfig.pageSize = size;
    MyTable.getDatas();
  },
  onShowSizeChange: (cur, size) => {
    MyTable.pageConfig.current = 1;
    MyTable.pageConfig.pageSize = size;
    MyTable.getDatas();
  },
};

// methods
MyTable.getDatas ||= (() => null);

MyTable.setDatas = (datas, total, page = MyTable.pageConfig.current) => {
  datas.forEach((val, index) => {
    Object.keys(val).forEach((key) => {
      let column = MyTable.columns.find((col) => col.key === key);
      if (column && column.customValue && column.customValue instanceof Function) {
        val[key] = column.customValue(val[key], index, val);
      }
    });
  });
  MyTable.datas = datas;
  MyTable.pageConfig.current = page;
  MyTable.pageConfig.total = total;
};

MyTable.setColumns = (columns) => {
  MyTable.columns = columns.map((v) => ({
    ...v,
    dataIndex: v.key,
    align: v.align || "center",
    ellipsis: true,
  }));
};

// lifecycle
onMounted(async () => {
  isLoading.value = true;
  MyTable.setColumns(MyTable.columns);
  await MyTable.getDatas();
  isLoading.value = false;
});
</script>

<style lang="less" scoped>
@import "./index.less";
</style>
